#include "ModelShip.h"
// #include <QPainter>
#include <QDebug>
#include "LonLatUtil.h"
#include "commonutil.h"

using namespace ns_yht;

// int ModelShip::sizeScale = 18;

ModelShip::ModelShip()
{
    mmsi = 0;
    cnname = "";
    enname = "";
    callsign = "";
    // channel = "";
    // device = "";

    // isInner = false;
    // id = 0;
    // aisAdd = 0;
    // gpsAdd = 0;

    // status = 0;
    imo = 0;
    rot = 128;
    // type = EShipType::Other;
    // epfd = 0;
    trueHeading = 511;
    cog = 511;
    sog = -1;
    lat = 91;
    lon = 181;
    stw = -1;
    // shipColor = "#00cc00";
    time = 0;
    draught = -1;
    // length = 1.0;
    // width = 1.0;
    source = 7;

    to_bow = 0;
    to_port = 0;
    to_stern = 0;
    to_starboard = 0;
}

ModelShip::~ModelShip()
{
}

int ModelShip::length() const
{
    return to_bow + to_stern;
}

int ModelShip::width() const
{
    return to_port + to_starboard;
}

bool ModelShip::outlineEnable() const
{
    // return (width() > 2 && length() > 4);
    return to_bow > 2 && to_stern > 2 && to_port > 2 && to_starboard > 2 && length() < 9000 && width() < 9000;
}

// double ModelShip::GetRotateCourse() const
// {
//     if (trueHeading >= 0 && trueHeading <= 360)
//     {
//         return trueHeading;
//     }
//     if (cog >= 0 && cog <= 360)
//     {
//         return cog;
//     }
//     return 0;
// }

int ModelShip::GetLengthClass()
{
    if (length() <= 40)
        return 1;
    else if (length() <= 80)
        return 2;
    else if (length() <= 120)
        return 4;
    else if (length() <= 160)
        return 8;
    else if (length() <= 240)
        return 16;
    else if (length() <= 320)
        return 32;
    else
        return 64;
}

bool ModelShip::containKey(const QString &key)
{
    return (QString::number(mmsi).contains(key) || enname.contains(key) || cnname.contains(key));
}

#if 0
void ModelShip::draw(QPainter &painter)
{
    QPointF center;
    // if (MyPublic::shipSmoothing && msgtype == 0 /* && dangerous*/)
    // {
    //     //自上次更新后，预测当前时间所在位置
    //     qint64 elapse = GlobalParam::getTime() - time;
    //     double speed =
    //         smoothingSpeedScale * sog * YBoost::MetersPerNM / 3600.; //转化为米/秒
    //     double distance = speed * elapse;
    //     YBoost::GetLonLat(lat, lon, cog, distance, lat2, lon2);

    //     center = EHHMAPBOX->pixelForCoordinate(Coordinate(lat2, lon2));
    // }
    // else
    center = EHHMAPBOX->pixelForCoordinate(Coordinate(lat, lon));
    // qInfo() << "center =============" << mmsi << lat << lon << center;
    QRect br = painter.clipRegion().boundingRect();
    if (center.x() < br.x() - 100 || center.x() > br.right() + 100 ||
        center.y() < br.y() - 100 || center.y() > br.bottom() + 100)
        return;

    painter.save();
    painter.translate(center);

    if (msgtype == 1)
    {
        drawArpa(painter);
        painter.restore();
        return;
    }

    if (msgtype == 3 || msgtype == 4 || msgtype == 5)
    { // MOB 红圈+叉叉
        painter.setPen(QPen(Qt::red, 2));
        painter.setBrush(Qt::NoBrush);
        double dhead = 2 * sizeScale;
        painter.drawEllipse(QPointF(0, 0), dhead, dhead);
        painter.drawLine(-dhead, -dhead, dhead, dhead);
        painter.drawLine(-dhead, dhead, dhead, -dhead);
    }
    else if (speedOverGround <= 1)
    { // 静止船舶
        painter.setPen(QPen(Qt::black, 1));
        int hr = sizeScale;
        if (msgtype == 2)
            painter.setBrush(QBrush("#b2d235")); //#ffFF12
        painter.drawEllipse(-hr, -hr, hr * 2, hr * 2);
    }
    else
    {
        // if (ModelShip2::m_northMode != ModelShip2::NMTrueNorth)
        // painter.rotate(-EHHMAPBOX->bearing());
        painter.save();
        painter.rotate(getAngle());

        //三角形和七边形，填充
        if (msgtype == 2)
            painter.setBrush(QBrush("#FFFF00"));
        double dhead;
        //        if (type == 1)
        {
            dhead = 2 * sizeScale;
            //            QPointF pts[3]{QPointF(0, -2 * sizeScale),
            //                        QPointF(-0.5 * sizeScale, sizeScale),
            //                        QPointF(0.5 * sizeScale, sizeScale)};

            QPointF pts[3]{QPointF(0, -2 * sizeScale),
                           QPointF(-1 * sizeScale, sizeScale),
                           QPointF(1 * sizeScale, sizeScale)};

            if (dangerous)
                painter.setPen(QPen(Qt::red, 2));
            else
                painter.setPen(QPen(Qt::black, 1));
            painter.drawPolygon(pts, 3);
        }
        //        else
        //        {
        //            dhead = 2.5 * sizeScale;
        //            QPointF pts[7]{QPointF(-0.5 * sizeScale, -1.5 * sizeScale),
        //                        QPointF(0, -2.5 * sizeScale),
        //                        QPointF(0.5 * sizeScale, -1.5 * sizeScale),
        //                        QPointF(0.5 * sizeScale, 1.3 * sizeScale),
        //                        QPointF(0.3 * sizeScale, 1.5 * sizeScale),
        //                        QPointF(-0.3 * sizeScale, 1.5 * sizeScale),
        //                        QPointF(-0.5 * sizeScale, 1.3 * sizeScale)};
        //            if (dangerous)
        //                painter.setPen(QPen(Qt::red, 2));
        //            else
        //                painter.setPen(QPen(Qt::black, 1));
        //            painter.drawPolygon(pts, 7);
        //        }

        if (turn != 0)
        {
            QPointF pts[3]{QPointF(0, -dhead), QPointF(0, -3 * sizeScale - dhead),
                           QPointF(0.75 * sizeScale * (turn > 0 ? 1 : -1),
                                   -3 * sizeScale - dhead)};
            painter.setPen(QPen(Qt::black, 1));
            painter.drawPolyline(pts, 3);
        }
        else
        {
            painter.setPen(QPen(Qt::black, 1));
            painter.drawLine(QPointF(0, -dhead), QPointF(0, -3 * sizeScale - dhead));
        }

        painter.restore();
        painter.rotate(courseOverGround);
        painter.setPen(QPen(Qt::black, 1, Qt::DashLine));
        double ssog = (speedOverGround > 30 ? 30 : speedOverGround);
        painter.drawLine(QPointF(0, 0), QPointF(0, -5 * sizeScale * ssog / 10.));
    }

    QString sname = getName();
    if (sname == "")
        sname = QString::number(mmsi);

    //船名
    if (msgtype != 3 && msgtype != 4 && msgtype != 5 && EHHMAPBOX->zoom() > 8 &&
        sname != "")
    {
        painter.resetTransform();
        painter.translate(center);

        painter.setPen(QPen(Qt::black, 1, Qt::DashLine));

        double angle = getAngle() - EHHMAPBOX->bearing();
        if (angle > 360)
            angle -= 360;
        else if (angle < 0)
            angle += 360;

        QMatrix m;
        if (angle > 90 && angle < 270)
            m.rotate(angle + 90);
        else
            m.rotate(angle - 90);

        QPoint pt1 = m.map(QPoint(0, 20));

        painter.setFont(QFont("宋体", 8));
        QFontMetrics fm = painter.fontMetrics();
        QRect rect = fm.boundingRect(sname);
        rect.setWidth(rect.width() + 2);
        rect.setHeight(rect.height() + 2);
        rect.moveTo(pt1.x() - 1, pt1.y() - rect.height() / 2 - 1);

        painter.setPen(QPen(Qt::gray, 1, Qt::DashLine));
        painter.drawLine(QPointF(0, 0), pt1);
        painter.setPen(QPen(Qt::gray, 1, Qt::SolidLine));
        painter.setBrush(QBrush("#80FFFFFF"));
        painter.drawRect(rect);
        painter.setPen(QPen(Qt::black, 1, Qt::SolidLine));
        painter.drawText(rect, Qt::AlignCenter, sname);
    }

    painter.restore();
}

void ModelShip::drawArpa(QPainter &painter)
{
    painter.save();

    //圆形，填充
    if (dangerous)
        painter.setPen(QPen(Qt::red, 2));
    else
        painter.setPen(QPen(QColor("#FFFF00"), 2));
    painter.setBrush(Qt::NoBrush);
    int hr = sizeScale;
    painter.drawEllipse(-hr, -hr, 2 * hr, 2 * hr);

    if (speedOverGround > 1)
    {
        // if (ModelShip::m_northMode != ModelShip::NMTrueNorth)
        // painter.rotate(-EHHMAPBOX->bearing());

        painter.rotate(courseOverGround);
        painter.setPen(QPen(Qt::black, 1, Qt::DashLine));
        double ssog = (speedOverGround > 30 ? 30 : speedOverGround);
        painter.drawLine(QPointF(0, 0), QPointF(0, -5 * sizeScale * ssog / 10.));
    }

    painter.restore();
}

#endif

double ModelShip::getAngle() const
{
    if (type == 11)
        return 0;

#if 1
    if (trueHeading >= 0 && trueHeading <= 360)
        return trueHeading;
    if (cog >= 0 && cog <= 360)
        return cog;
#endif

#if 0
    if (sog < 4)
    { // 速度小于4节，船艏向优先
        if (trueHeading >= 0 && trueHeading <= 360)
            return trueHeading;
        if (cog >= 0 && cog <= 360)
            return cog;
    }
    else
    { // 速度大于4节，航迹向优先
        if (cog >= 0 && cog <= 360)
            return cog;
        if (trueHeading >= 0 && trueHeading <= 360)
            return trueHeading;
    }
#endif
    return 0;
}

// void ModelShip::drawSelectedBox(QPainter &painter)
//{
// }

QString ModelShip::getTypeString() const
{
    QString s;
    if (type >= 20 && type < 30)
        s = "地效翼船(WIG)";
    else if (30 == type)
        s = "捕捞";
    else if (31 == type)
        s = "拖船";
    else if (32 == type)
        s = "拖船且推带长度超过200m或宽度超过25m";
    else if (33 == type)
        s = "从事挖掘或水下作业";
    else if (34 == type)
        s = "从事潜水作业";
    else if (35 == type)
        s = "从事军事行动";
    else if (36 == type)
        s = "帆船";
    else if (37 == type)
        s = " 游艇";
    else if (type >= 40 && type < 50)
        s = "高速船(HSC)";
    else if (50 == type)
        s = "引航船舶";
    else if (51 == type)
        s = "搜救船舶";
    else if (52 == type)
        s = "拖轮";
    else if (53 == type)
        s = "港口补给船";
    else if (54 == type)
        s = "安装有防污染设施或设备的船舶";
    else if (55 == type)
        s = "执法船舶";
    else if (58 == type)
        s = "医疗运送船舶";
    else if (59 == type)
        s = "非武装冲突参与国的船舶和航空器";
    else if (type >= 60 && type < 70)
        s = "客轮";
    else if (type >= 70 && type < 80)
        s = "货轮";
    else if (type >= 80 && type < 90)
        s = "油轮";
    else if (11 == type) // 自定义
        s = "网位移";
    else if (12 == type) // 自定义
        s = "航标";
    else
        s = "其它";
    return s;
}

QString ModelShip::getStatusString() const
{
    QString returnString = "";
    if (navigationStatus == 0)
    {
        returnString = "发动机使用中(0)";
    }
    else if (navigationStatus == 1)
    {
        returnString = "锚泊(1)";
    }
    else if (navigationStatus == 2)
    {
        returnString = "未操纵(2)";
    }
    else if (navigationStatus == 3)
    {
        returnString = "操作受限(3)";
    }
    else if (navigationStatus == 4)
    {
        returnString = "吃水受限(4)";
    }
    else if (navigationStatus == 5)
    {
        returnString = "靠泊(5)";
    }
    else if (navigationStatus == 6)
    {
        returnString = "搁浅(6)";
    }
    else if (navigationStatus == 7)
    {
        returnString = "捕捞(7)";
    }
    else if (navigationStatus == 8)
    {
        returnString = "航行(8)";
    }
    else
    {
        returnString = "未定义(" + QString::number(navigationStatus) + ")";
    }

    return returnString;
}

ShipStatusOfSog ModelShip::getStatusOfSog() const
{
    if (sog <= 2)
        return ShipStatusOfSog::Anchoring;
    else
        return ShipStatusOfSog::Voyaging;
}

void ModelShip::setType(int aisType)
{
    // 已经有了类型就不再设置，这样手动设定的保存在数据库中的类型可以起作用
    if (type > 0)
        return;

    // qInfo() << "1E8==" << 1E8 << (100000000 == 1E8) << mmsi;
    // qInfo() << "" << aisType << mmsi << (mmsi >= 1E8 && mmsi < 1E9) << (mmsi >= 99E7 && aisType < 20) << sog << enname << (enname.isEmpty() && sog < 1) << (enname.startsWith("NET") || (enname.contains("-") && sog < 1));

    if (mmsi >= 1E8 && mmsi < 1E9)
    {
        if (mmsi >= 99E7 && aisType < 20)
        {
            // qInfo() << "mmsi >= 99E7 && aisType < 20";
            setAsCustomType(12);
            return;
        }
        // if (enname.isEmpty() && sog < 1)
        // {
        //     qInfo() << "enname.isEmpty() && sog < 1";
        //     setAsCustomType(11);
        //     return;
        // }
    }
    // else if (sog < 1)
    // {
    //     qInfo() << "！=9位mmsi && sog < 1";
    //     setAsCustomType(11);
    //     return;
    // }
    if (!enname.isEmpty())
    {
        if (enname.startsWith("NET") || (enname.contains("-") && sog < 1))
        {
            // qInfo() << "enname.startsWith( NET) || (enname.contains( - ) && sog < 1)";
            setAsCustomType(11);
            return;
        }
    }

    type = aisType;
}

void ModelShip::setAsCustomType(int stype)
{
    type = stype;
    cog = 0;
    // sog = 0;
    trueHeading = 0;
}

void ModelShip::setMsgType(const QString smtype)
{
    if (smtype == "AIS")
        msgtype = EMsgType::AIS;
    else if (smtype == "ARPA")
        msgtype = EMsgType::ARPA;
    else if (smtype == "SART")
        msgtype = EMsgType::SART;
    else if (smtype == "MOB")
        msgtype = EMsgType::MOB;
    else if (smtype == "EPIRB")
        msgtype = EMsgType::EPIRB;
    else // if(smtype=="FUSE")
        msgtype = EMsgType::FUSED;

    //    spdlog::info("ModelShip2::setMsgType - smtype - {}   msgtype -
    //    {}",smtype.toStdString(),msgtype);
    //    MyPublic::gLogger->info("ModelShip2::setMsgType - smtype - {}   msgtype
    //    - {}",smtype.toStdString(),msgtype);
}

// yhtc  navigationStatus str->int
void ModelShip::setNavigationStatus(const QString navStatus)
{
    if (navStatus == "动力航行中" || navStatus == "风帆动力航行")
        navigationStatus = 8;
    else if (navStatus == "锚链系泊")
        navigationStatus = 1;
    else
        navigationStatus = 2;
}

QString ModelShip::getName() const
{
    return cnname == "" ? (enname == "" ? QString::number(mmsi) : enname) : cnname;
}

int ModelShip::getShipType() const
{
    int s;
    if (type >= 31 && type <= 33)
        s = EShipType::Drag;
    else if (type == 52)
        s = EShipType::Drag;
    else if (type >= 60 && type < 70)
        s = EShipType::Guest;
    else if (type >= 70 && type < 80)
        s = EShipType::Cargo;
    else if (type >= 80 && type < 90)
        s = EShipType::Oil;
    else if (11 == type) // 自定义
        s = EShipType::NetMark;
    else if (12 == type) // 自定义
        s = EShipType::NavigationMark;
    else if (type == 30 || type == 40)
        s = EShipType::Fish;
    else
        s = EShipType::Other;
    return s;
}
